#pragma once
#include "fields.hpp"
#include <memory>
#include <functional>
namespace bitrpc
{
    class BaseMessage
    {
    public:
        using ptr = std::shared_ptr<BaseMessage>;
        virtual ~BaseMessage() {};
        // 设置消息id
        virtual void SetId(std::string rid)
        {
            _rid = rid;
        }
        // 提供消息id
        virtual std::string rid() { return _rid; }
        // 设置消息类型
        virtual void SetMessageType(MessageType mt)
        {
            _mytype = mt;
        }
        // 提供消息类型
        virtual MessageType messageType() { return _mytype; }
        virtual std::string Serialize() = 0;                  // 序列化
        virtual bool DeSerialize( std::string &msg) = 0; // 反序列化
        virtual bool check() = 0;                             // 进行消息检查

    private:
        // 无论是什么样的消息，都要有消息类型和消息id这两个报头字段
        std::string _rid;
        MessageType _mytype;
    };
    class BaseBuffer
    {
    public:
        using ptr = std::shared_ptr<BaseBuffer>;
        virtual ssize_t readableSize() = 0;                   // 返回缓冲区中有多少字节数据
        virtual int32_t peekInt32() = 0;                      // 读取缓冲区前四字节数据
        virtual void retrieveInt32() = 0;                     // 移除四个字节
        virtual int32_t readInt32() = 0;                      // 读取缓冲区前四字节数据并移除四个字节
        virtual std::string retrieveAsString(size_t len) = 0; // 将缓冲区数据全部读取出来
    private:
    };
    class BaseProtocol
    {
    public:
        using ptr = std::shared_ptr<BaseProtocol>;
        virtual bool canProcessed(const BaseBuffer::ptr &buf) = 0;                     // 看看缓冲区内是否有数据
        virtual bool onMessage(const BaseBuffer::ptr &buf, BaseMessage::ptr &msg) = 0; // 处理缓冲区内数据
        virtual std::string serialize(const BaseMessage::ptr &msg) = 0;// 对处理后的消息进行序列化
    }; 
    class BaseConnection
    {
    public:
        using ptr = std::shared_ptr<BaseConnection>;
        virtual void send(const BaseMessage::ptr &msg) = 0;
        virtual void shutdown() = 0;
        virtual bool connected() = 0;
    };
    using ConnectionCallback = std::function<void(const BaseConnection::ptr &)>;
    using CloseCallback = std::function<void(const BaseConnection::ptr &)>;
    using MessageCallback = std::function<void(const BaseConnection::ptr &,
                                               BaseMessage::ptr &)>;
    class BaseServer
    {
    public:
        using ptr = std::shared_ptr<BaseServer>;
        virtual void setConnectionCallback(const ConnectionCallback &cb)
        {
            _cb_connection = cb;
        }
        virtual void setCloseCallback(const CloseCallback &cb)
        {
            _cb_close = cb;
        }
        virtual void setMessageCallback(const MessageCallback &cb)
        {
            _cb_message = cb;
        }
        virtual void start() = 0;

    protected:
        ConnectionCallback _cb_connection;
        CloseCallback _cb_close;
        MessageCallback _cb_message;
    };
    class BaseClient
    {
    public:
        using ptr = std::shared_ptr<BaseClient>;
        virtual void setConnectionCallback(const ConnectionCallback &cb)
        {
            _cb_connection = cb;
        }
        virtual void setCloseCallback(const CloseCallback &cb)
        {
            _cb_close = cb;
        }
        virtual void setMessageCallback(const MessageCallback &cb)
        {
            _cb_message = cb;
        }
        virtual void connect() = 0;//建立连接
        virtual void shutdown() = 0;//关闭连接
        virtual bool send(const BaseMessage::ptr & msg) = 0;//发送消息
        virtual BaseConnection::ptr connection() = 0;//获取连接对象
        virtual bool connected() = 0;//判断连接是否正常

    protected:
        ConnectionCallback _cb_connection;
        CloseCallback _cb_close;
        MessageCallback _cb_message;
    };
};
